home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacTech 1 to 12
/
MacTech-vol-1-12.toast
/
Tools
/
Bare Bones PopupFuncs 2.8.2
/
xPop ƒ
/
comment.c
next >
Wrap
C/C++ Source or Header
|
1992-07-01
|
7KB
|
303 lines
#include <SetupA4.h>
#include "xpop.h"
enum { kUnknown, kUncomment, kComment };
XPopRecPtr gPopRec;
void DoInit(void);
void DoClose(void);
void DoFOpen(void);
void DoFClose(void);
void DoQuery(void);
void DoIt(void);
Boolean Comment( Handle txt, short language );
Boolean Uncomment( Handle txt, short language );
short CountLines( Handle txt );
void PickComment( short language, short *commentSize, char **comment, char **endcomment );
/*------------------------------------------------------------*/
pascal void main( XPopRecPtr paramPtr)
{
RememberA0();
SetUpA4();
gPopRec = paramPtr;
switch (paramPtr->message) {
case xpop_init: DoInit(); break;
case xpop_close: DoClose(); break;
case xpop_fopen: DoFOpen(); break;
case xpop_fclose: DoFClose(); break;
case xpop_query: DoQuery(); break;
case xpop_doit: DoIt(); break;
}
RestoreA4();
} /* main */
/*---------------*/
void DoInit(void)
{
InitRecPtr initStuff;
SelectionRecPtr selection;
selection = (SelectionRecPtr) gPopRec->param;
initStuff = (InitRecPtr) NewPtr(sizeof(InitRec));
if ( initStuff!=NIL ) {
initStuff->version = 1;
initStuff-> language = (1 << _c) | (1 << _cplusplus) |
(1 << _pascal) | (1 << _objectpascal) |
(1 << _rez) | (1<<_asm);
initStuff-> writes = true;
initStuff-> sensitive = true;
initStuff-> getFileMsgs = false;
initStuff-> selStuff = kNeedSelection;
initStuff-> environment = (1 << kMPW) | (1<< kTHINK)| (1<< kGENERIC);
}
gPopRec->result = (long) initStuff;
}
/*---------------*/
void DoClose(void)
{}
/*---------------*/
void DoFOpen(void)
{}
/*---------------*/
void DoFClose(void)
{}
/*---------------*/
void DoQuery(void)
{
SelectionRecPtr selection;
short which;
which = kUnknown;
gPopRec->result = (long) "\pComment(";
selection = (SelectionRecPtr) gPopRec->param;
if ( selection->selEnd == selection->selStart ||
selection->hText == NIL ) /* can't comment if it ain't selected */
return;
switch ( selection->language ) {
case _c:
case _cplusplus:
case _rez:
if ( **selection->hText == '/' && *( (*selection->hText)+1)=='*' )
which = kUncomment;
else
which = kComment;
break;
case _pascal:
case _objectpascal:
if ( **selection->hText == '{' )
which = kUncomment;
else
which = kComment;
break;
case _asm:
which = ( **selection->hText == ';' ) ? kUncomment : kComment;
break;
} /* switch */
switch ( which ) {
case kUncomment: gPopRec->result = (long) "\pUncomment"; break;
case kComment: gPopRec->result = (long) "\pComment"; break;
}
gPopRec->private = which;
}
/*---------------*/
void DoIt(void)
{
SelectionRecPtr selection;
PostDoRecPtr rec;
Boolean result;
selection = (SelectionRecPtr) gPopRec->param;
rec = (PostDoRecPtr) NewPtr(sizeof(PostDoRec));
if ( rec ) {
/* gPopRec->private was set during the query message */
if ( gPopRec->private == kComment )
result = Comment( selection->hText, selection->language );
else
result = Uncomment( selection->hText, selection->language );
rec->version = 1;
rec->paste = ( gPopRec->private != 0 && result );
rec->where = kReplace;
}
gPopRec->result = (long) rec;
}
/*---------------*/
Boolean Comment( Handle txt, short language );
Boolean Comment( Handle txt, short language )
{
short commentSize;
char *comment, *endcomment, *pos, *newPos, *stop;
short lineCount;
long len;
Handle newText;
PickComment( language, &commentSize, &comment, &endcomment );
lineCount = CountLines( txt );
len = GetHandleSize( txt );
/* For simplicity, I allocate another handle to put the commented text into.*/
/* People tight on memory who desire to comment a large block of text will not*/
/* be happy with this.*/
newText = NewHandle( len + 2 * commentSize * (lineCount+1) + 128 );
if ( ! newText ) {
SysBeep(30);
goto failed;
}
pos = *txt;
stop = pos + len;
newPos = *newText;
/* Comment the beginning */
BlockMove( comment, newPos, commentSize );
newPos += commentSize;
/* Comment the middle */
while ( pos < stop ) {
while ( *pos!='\r' && pos < stop ) {
if ( (*pos == *endcomment) && (commentSize==1 || *(pos+1)==*(endcomment+1))) {
*newPos++ = '»';
pos += commentSize;
}
else
*newPos++ = *pos++;
} /* copy and alter line */
if ( pos < stop ) {
BlockMove( endcomment, newPos, commentSize);
newPos += commentSize;
*newPos++ = *pos++;
}
if ( pos < stop ) {
BlockMove( comment, newPos, commentSize);
newPos+= commentSize;
}
}
/* ... and now the end */
if ( *(newPos-1) != '\r' ) {
BlockMove( endcomment, newPos, commentSize);
newPos += commentSize;
}
/* save the changes */
len = newPos - *newText;
HUnlock( txt );
SetHandleSize( txt, len );
HLock( txt );
BlockMove( *newText, *txt, len );
DisposHandle( newText );
return true;
failed:
return false;
}
/*---------------*/
Boolean Uncomment( Handle txt, short language )
{
short commentSize;
char *comment, *endcomment, *pos, *newPos, *stop;
short lineCount;
long len;
Handle newText;
PickComment( language, &commentSize, &comment, &endcomment );
lineCount = CountLines( txt );
len = GetHandleSize( txt );
newText = NewHandle( len ); /* more than needed */
if ( ! newText ) {
SysBeep(30);
goto failed;
}
pos = *txt;
stop = pos + len;
newPos = *newText;
/* unComment the beginning */
pos += commentSize;
/* unComment the middle */
while ( pos < stop ) {
while ( *pos!='\r' && pos < stop ) {
if ( *pos=='»' ) {
BlockMove( endcomment, newPos, commentSize );
newPos+= commentSize;
pos++;
}
else
*newPos++ = *pos++;
} /* copy and alter line */
if ( pos < stop ) {
/* erase the commentend at the end of line */
if ( (*(pos-commentSize) == *endcomment) && (commentSize==1 || *(pos-1)==*(endcomment+1))) {
newPos -= commentSize;
}
*newPos++ = *pos++;
/* skip the comment at the beginning of line */
if ( (*pos == *comment) && (commentSize==1 || *(pos+1)==*(comment+1)) )
pos += commentSize;
}
}
/* ... and now the end */
if ( (*(pos-commentSize) == *endcomment) && (commentSize==1 || *(pos-1)==*(endcomment+1))) {
newPos -= commentSize;
}
/* save the changes */
len = newPos - *newText;
SetHandleSize( txt, len );
BlockMove( *newText, *txt, len );
DisposHandle( newText );
return true;
failed:
return false;
} /* Uncomment */
/*---------------*/
short CountLines( Handle txt )
{
register char *p,*stop;
short cnt;
stop = *txt + GetHandleSize(txt);
for ( p=*txt,cnt=0; p<stop; p++ )
if (*p=='\r')
cnt++;
return cnt;
} /* CountLines() */
/*----------------*/
void PickComment( short language, short *commentSize, char **comment, char **endcomment )
{
if ( language==_c || language== _cplusplus || language== _rez ) {
*commentSize = 2;
*comment = "/*";
*endcomment = "*/";
}
else if ( language==_pascal || language== _objectpascal ) {
*commentSize = 1;
*comment = "{";
*endcomment = "}";
}
else if ( language==_asm ) {
*commentSize = 1;
*comment = ";";
*endcomment = " ";
}
} /* PickComment */
/*----------------*/